//
/*   CUDA helper code
*    Copyright (C) 2009 Goffredo Marocchi
*
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License along
*    with this program; if not, write to the Free Software Foundation, Inc.,
*    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef IGGS_CUDA_CHECKS_H_
#define IGGS_CUDA_CHECKS_H_

#if _GLIBCXX_CSTDIO == 1

#else
	#include <cstdio>
#endif

#define SafeThreadSync(msg)	__SafeThreadSync ((msg), __FILE__, __LINE__)


/**\brief Synchronization function
 *
 * This function synchronizes CUDA threads execution and checks for errors \n
 * (necessary to check kernel execution errors as the kernel launches are non-blocking/asynchronous)
 *
 * \param msg error message we want to print to stderr if we detect an error, const char*
*  \param file name of the file this function was invoked from, const char*
*  \param line line number of the function call, const int
 * \return void
 */
inline void __SafeThreadSync (const char* msg, const char* file, const int line) {

    cudaError err = cudaThreadSynchronize();

    if ( cudaSuccess != err) {

    	fprintf(stderr, "%s failure... '%s' in line %i : %s.\n",
                msg, file, line, cudaGetErrorString( err) );
        exit(EXIT_FAILURE);

    }

	return;

}

/**\brief Error checking function
 *
 * This function checks for errors in the CUDA method invoked
 *
 * \param msg error message we want to print to stderr if we detect an error, const char*
*  \param file name of the file this function was invoked from, const char*
*  \param line line number of the function call, const int
 * \return void
 */
inline void CheckCall (const char* msg, cudaError err, const char *file, const int line)
{
    if( cudaSuccess != err)
    {
        fprintf(stderr, "Cuda error: %s:  in file <%s>, line %i : %s.\n",
                   msg,  file, line, cudaGetErrorString( err) );
        exit(EXIT_FAILURE);
    }
}

/**\brief Error checking function
 *
 * This malloc() wrapper checks for the validity of the pointer returned by the malloc() function running on the host.
 *
 * \param msg error message we want to print to stderr if we detect an error, const char*
*  \param file name of the file this function was invoked from, const char*
*  \param line line number of the function call, const int
 * \return void
 */
inline void CheckMalloc( void *pointer, const char *file, const int line )
{
    do {
        if( !(pointer)) {
            fprintf(stderr, "Host malloc failure in file <%s>, line %i\n",
                    file, line);
            exit(EXIT_FAILURE);
        }
    } while (0);
}


#endif /* IGGS_CUDA_CHECKS_H_ */
